<?php

/**
 *
 * This file is a helper file, providing efficient autoloading
 * and configuration mechanisms for Mongrove in the case of an
 * absent framework which could govern this procedure.
 *
 * @author Michiel Hakvoort <michiel@hakvoort.it>
 * @author Gido Hakvoort <gido@hakvoort.it>
 *
 */

namespace mongrove;

/**
 * If Mangrove is used, don't require class loading
 */
if(defined('MG_VERSION')) {
    return;
}

/**
 * Effective class resolution through exhaustion
 */
spl_autoload_register(function($reqClassName) {
    $reqClassName = mb_strtolower($reqClassName);

    static $classes;

    if(!isset($classes)) {
        $root = realpath(__DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'src') . DIRECTORY_SEPARATOR;

        $byFile = array();
        $byFile["{$root}Collection.php"] = array(true, 'CollectionQueryService');
        $byFile["{$root}CollectionManager.php"] = array(true, 'SimpleCollectionManagerProvider', 'MangroveCollectionManagerProvider', 'CollectionManagerProvider');
        $byFile["{$root}Command.php"] = array(true);
        $byFile["{$root}Constant.php"] = array(true);
        $byFile["{$root}Create.php"] = array(true);
        $byFile["{$root}DatabaseManager.php"] = array(true);
        $byFile["{$root}Field.php"] = array('AbstractField', 'AbstractAtomicField', 'SimpleField', 'CompositeField');
        $byFile["{$root}Query.php"] = array(true);
        $byFile["{$root}QueryResult.php"] = array(true);
        $byFile["{$root}Record.php"] = array(true);
        $byFile["{$root}RevisionCollection.php"] = array();
        $byFile["{$root}RevisionRecord.php"] = array();
        $byFile["{$root}Structure.php"] = array(true);

        $root = "{$root}field" . DIRECTORY_SEPARATOR;

        $byFile["{$root}DateField.php"] = array(true);
        $byFile["{$root}EmailField.php"] = array(true);
        $byFile["{$root}EnumField.php"] = array(true);
        $byFile["{$root}FloatField.php"] = array(true);
        $byFile["{$root}IntegerField.php"] = array(true);
        $byFile["{$root}ListField.php"] = array(true, 'ListFieldIterator');
        $byFile["{$root}MapField.php"] = array(true, 'MapFieldIterator');
        $byFile["{$root}ReferenceField.php"] = array(true);
        $byFile["{$root}StringField.php"] = array(true);
        $byFile["{$root}StructureField.php"] = array(true);
        
        $root = "{$root}atomic" . DIRECTORY_SEPARATOR;
        
        $byFile["{$root}AtomicIntegerField.php"] = array(true);

        $classes = array();

        $prefix = 'mongrove\\';

        foreach($byFile as $file => $classNames) {
            $impliedClassName = basename($file, '.php');

            foreach($classNames as $className) {
                if($className === true) {
                    $className = $impliedClassName;
                }
                $className = mb_strtolower($className);
                $classes["{$prefix}{$className}"] = $file;
            }
        }
    }

    if(isset($classes[$reqClassName])) {
        include($classes[$reqClassName]);
    }
});

/**
 * This utility class provides a simple way to set up
 * a functioning Mongrove environment.
 *
 * @author Michiel Hakvoort <michiel@hakvoort.it>
 * @author Gido Hakvoort <gido@hakvoort.it>
 */
class Mongrove {

    /**
     * Set the MongoDB handles which can be used for interaction
     * with Mongo.
     *
     * @param array[MongoDB]|MongoDB $... The first array of MongoDB handles or MongoDB handle to add
     * @param array[MongoDB]|MongoDB $... The second array of MongoDB handles or MongoDB handle to add
     * @param array[MongoDB]|MongoDB $... etc...
     */
    public static function setup() {
        $databases = array();
        $args = func_get_args();

        foreach($args as $dbOrArray) {
            if(is_array($dbOrArray)) {
                foreach($dbOrArray as $db) {
                    $databases[] = $db;
                }
            } else {
                $databases[] = $dbOrArray;
            }
        }

        CollectionManager :: setCollectionManagerProvider(
                                    new SimpleCollectionManagerProvider(
                                        new CollectionManager(
                                            new DatabaseManager($databases)
                                        )));
    }

}
